/* preproc.h: заголовочный файл, содержащий определения типов и структур даннных, а также констант*/

#ifndef PREPROC_H
#define PREPROC_H

//============= Режим программы =====================================================
// #define DEBUG_INTERPRETER	// режим отладки функций интерпретатора
#define TREE_SHOW_MORE		// режим отображения полной информации об узле дерева
#define	SHOW_TRASH			// режим отображения корзины
//===================================================================================

//===================================== Константы ================================================================================
//----------- Пределы ----------------------------------------------//
#define MAX_ARGS 			31										// константа максимального количества аргументов функции
#define MAX_LEN				127										// константа максимальной длины строки
#define MAX_ALLOCATED_MEM	1023									// константа максимального количества блоков выделенной памяти
#define MAX_OBJ 			127										// константа максимального количества объектов
//----------- Результаты работы функций ----------------------------//
#define SUCCESS             0										// константа "успех"
#define ERROR				-1										// константа "ошибка"
#define SYNTAX_ERROR		-2										// константа "ошибка синтаксиса"
#define EXIST_ERROR			-3										// константа "ошибка существования"
//----------- Логические константы и операторы ---------------------//
#define TRUE 				1										// константа "истина"
#define FALSE				0										// константа "ложь"
#define or 					||										// переопределение оператора "или"
#define and					&&										// переопределение оператора "и"
//----------- Интерфейс интерпретатора -----------------------------//
#define GREETINGS			'>'										// символ "приглашения"
#define MOTD                "Welcome back.\n"						// Message Of The Day
#define CMD_NOT_FOUND		"Command not found.\n"					// команда не найдена
#define RELOADCONF_C		"reloadconf"							// команда перезагрузки КФ
#define LOADCONF_C			"loadconf"								// команда загрузки КФ
#define SHOWTREE_C			"showtree"								// команда отображения дерева
#define SHOWTRASH_C			"showtrash"								// команда отображения корзины
#define	HELP_C				"help"									// команда вывода справки
#define	FUNCS_C				"funcs"									// команда вывода всех функций
#define SUCCESS_STR			"Success!"								// строка сообщения об удачном завершении
#define ERROR_STR			"Error!"								// строка сообщения об неудачном завершении
//----------- Константы поддержки указателей -----------------------//
#define EOS 				'\0'									// символ конца строки
#define NULL 				0										// константа нуля (для инициализации указателей)
//----------- Типы файлов интерпретатора ---------------------------//
#define	NOT_INTERPRET_FILE	0
#define	HELP_FILE			1
#define	CONF_FILE			2
#define	DESC_FILE			3
//----------- Типы объектов ----------------------------------------//
#define OBJ_T    			0										// константа "объект - объект"
#define STR_T        		1										// константа "объект - строка"
#define FILH_T				2										// константа "объект - файл"
#define PTH_T 				3										// константа "объект - папка"
#define GBG_T				4										// константа "объект - мусор"
//----------- Внешние файлы ----------------------------------------//
#define WIN_LIB             ".dll"									// константа пути до динамических библиотек windows (.dll)
#define NIX_LIB             ".so"									// константа пути до динамических библиотек linux (.so)
#define HELP_FILE_PATH		"help.desc"								// константа пути до файла помощи
#define CONF_FILE_PATH		"comm.conf"								// константа пути до конфигурационного файла
#define	DESC_FILE_PATH		"comm.desc"								// константа пути до файла описаний функций
//================================================================================================================================

//===================================== Макросы ========================================================================
#define TEST(cmd, value)    			(get_hash(cmd) == get_hash(value))?1:0	// макрос сравнения двух строк по хэшу
#define str_to_int						atoi									// переопределение функции atoi
#define create_str_obj(name, string)	create_object(name, STR_T, string)
#define create_filh_obj(name, filh)		create_object(name, FILH_T, filh)
#define create_pth_obj(name, path)		create_object(name, PTH_T, path)
//========================================================================================================================

//============= Внешние подключения =====================================================
#include <stdio.h>		// подключение библиотеки ввода/вывода
#include <string.h>		// подключение библиотеки для работы со строками
#include <stdlib.h>		// подключение библиотеки стандартных функций


#ifdef _WIN32
#include <conio.h>
#include <windows.h>	// подключение библиотеки Windows API
#endif

#ifdef __linux__
#include <dlfcn.h>		// подключение библиотеки для работы с динамическими библиотеками
//#include "lib.h"
#endif
//========================================================================================

//========================== Типы данных, структуры и функции ============================
//--------- Типы данных --------------------//
typedef char*				string;			// строка
typedef char*				flag_t;			// ключ (флаг)
typedef unsigned int		uint;			// беззнаковый int
typedef unsigned short	int	usint;			// беззнаковый короткий int
typedef unsigned short	int type_t;			// тип "объект
typedef int					rc_t;			// тип "возращаемое значение"
typedef string  			pth_t;			// тип "путь"
typedef string				dir_t;			// дирректория

//--------- Структуры ----------------------//
typedef struct								// структура, описывающая объект списка
{
	string			name;					// имя объекта
	type_t			type;					// тип данных в объекте
	void*			data;					// данные узла
	struct obj_t* 	next;					// указатель на следующий объект
} obj_t;
///////////////////////////////////////////////
typedef struct								// структура описывающая глобальные значения для подгружаемых функций
{
	obj_t*	root_obj;						// корневой объект списка
	obj_t*	last_obj;						// последний объект списка
	usint	obj_count;						// количество объектов списка
	pth_t 	curr_dir;						// текущая директория
	rc_t	result;							// код результата
} gvars_t;
//////////////////////////////////////////////
//--------- Функции ------------------------//
typedef void (*import_fn_t)(int, string*, gvars_t*);	// прототип указателя на "стандартную" функцию
//////////////////////////////////////////////
typedef struct								// структура, описывающая узел дерева
{
	int					hash;				// хеш-код имени функции
	string				name,				// имя вызываемой функции
						fname;				// реальное имя функции

	int					argc;				// количество аргументов функции
	string				desc;				// описание вызываемой функции

	pth_t				dll_path;			// путь до библиотеки

	import_fn_t			fn;					// поле, хранящее адрес функции
	void*				hlib;				// указатель библиотеки

    struct fn_node_t*	right;				// указатель правого поддерева
	struct fn_node_t*	left;				// указатель левого поддерева
} fn_node_t;
//////////////////////////////////////////////
typedef struct								// структура, описывающая позиции частей строки конфигурационного файла
{
	usint	using_name,						// позиция используемого имени
			func_name,						// позиция имени функции в библиотеке
			args_count,						// позиция количества аргументов
			desc,							// позиция метки описания
			dll_path;						// позиция пути до библиотеки с функцией
} conf_template;
//========================================================================================

//================ Глобальные переменные, массивы и указатели ==========================================
static void*		trash[MAX_ALLOCATED_MEM];	// массив указателей на всю выделенную память: "корзина"
static usint		trash_p		= 0;			// переменная, хранящая номер свободной ячейки корзин
static fn_node_t*	root_tree	= NULL;			// корневой узел дерева
static gvars_t* 	gvars 		= NULL;			// структура глобальных переменных
//======================================================================================================


#endif
